package org.misty.blog.controller;

import org.misty.blog.po.Article;
import org.misty.blog.po.User;
import org.misty.blog.service.ArticleService;
import org.misty.blog.service.CategoryService;
import org.misty.blog.service.TagService;
import org.misty.blog.vo.ArticleQuery;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.thymeleaf.util.StringUtils;

import javax.servlet.http.HttpSession;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Controller
@RequestMapping("/admin")
public class BlogController {
    public static final String INPUT = "admin/blogs-input";
    public static final String LIST = "admin/blogs";
    public static final String REDIRECT_LIST = "redirect:/admin/blogs";

    private final ArticleService articleService;
    private final CategoryService categoryService;
    private final TagService tagService;

    public BlogController(ArticleService articleService, CategoryService categoryService, TagService tagService) {
        this.articleService = articleService;
        this.categoryService = categoryService;
        this.tagService = tagService;
    }

    @GetMapping("/blogs")
    public String blogs(@PageableDefault(size = 2, sort = {"updateTime"}, direction = Sort.Direction.DESC) Pageable pageable,
                        ArticleQuery search,
                        Model model) {
        model.addAttribute("page", articleService.listArticles(pageable, search));
        model.addAttribute("categories", categoryService.listCategory());
        return LIST;
    }

    @PostMapping("/blogs/search")
    public String serach(@PageableDefault(size = 2, sort = {"updateTime"}, direction = Sort.Direction.DESC) Pageable pageable,
                         ArticleQuery search,
                         Model model) {
        model.addAttribute("page", articleService.listArticles(pageable, search));
        return "admin/blogs::blogList";
    }

    @GetMapping("/blogs/input")
    public String input(Model model) {
        model.addAttribute("article", new Article());
        fillCategoryAndTag(model);
        return INPUT;
    }

    @GetMapping("/blogs/{id}/input")
    public String editInput(@PathVariable Long id, Model model) {
        model.addAttribute("article", articleService.getArticle(id).orElse(null));
        fillCategoryAndTag(model);
        return INPUT;
    }

    @PostMapping("/blogs")
    public String post(Article article, RedirectAttributes redirectAttrs, HttpSession session) {
        User user = (User) session.getAttribute("user");
        article.setUser(user);
        article.setCategory(categoryService.getCategory(article.getCategory().getId()).orElse(null));
        article.setTags(tagService.listTags(splitIds(article.getTagIds())));

        if (article.getId() == null) {
            articleService.saveArticle(article);
        } else {
            articleService.updateArticle(article.getId(), article);
        }

        return REDIRECT_LIST;
    }

    @RequestMapping("/blogs/{id}/delete")
    public String delete(@PathVariable Long id, RedirectAttributes redirectAttr) {
        articleService.deleteArticle(id);
        redirectAttr.addFlashAttribute("message", "删除成功");
        return REDIRECT_LIST;
    }


    private List<Long> splitIds(String ids) {
        if (StringUtils.isEmptyOrWhitespace(ids)) {
            return Collections.emptyList();
        }
        return Arrays.stream(ids.split(",")).map(Long::new).collect(Collectors.toList());
    }

    private void fillCategoryAndTag(Model model) {
        model.addAttribute("categories", categoryService.listCategory());
        model.addAttribute("tags", tagService.listTags());
    }
}
